using FreeSql;
using KrasDD.Dtos;
using KrasDD.Models;
using KrasDD.Services.Interfaces;
using Microsoft.AspNetCore.Mvc;

namespace KrasDD.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class EventTestController : ControllerBase
    {
        private readonly IDocumentService _documentService;
        private readonly IMethodService _methodService;
        private readonly IServerEventService _serverEventService;
        private readonly IFreeSql _freeSql;

        public EventTestController(
            IDocumentService documentService,
            IMethodService methodService,
            IServerEventService serverEventService,
            IFreeSql freeSql
        )
        {
            _documentService = documentService;
            _methodService = methodService;
            _serverEventService = serverEventService;
            _freeSql = freeSql;
        }

        /// <summary>
        /// 创建测试数据
        /// </summary>
        [HttpPost("setup-test-data")]
        public async Task<ApiResponse<string>> SetupTestData()
        {
            try
            {
                // 1. 创建测试METHOD
                var testMethod = new METHOD
                {
                    ID = Guid.NewGuid().ToString("N"),
                    NAME = "Test Event Method",
                    METHOD_CODE =
                        @"var document = e.CustomerParms as DOCUMENT;
                            if (document != null)
                            {
                                document.KEYED_NAME = document.KEYED_NAME + DateTime.Now ;
                                document.DESCRIPTION = ""Processed by event handler at "" + DateTime.Now.ToString();
                                Console.WriteLine($""Event processed: {document.ID}"");
                            }
                            return e.CustomerParms;",
                    METHOD_TYPE = "C#",
                    CREATED_BY_ID = "SYSTEM",
                    CREATED_ON = DateTime.Now,
                    CONFIG_ID = "DEFAULT_CONFIG",
                    PERMISSION_ID = "DEFAULT_PERMISSION",
                    OWNED_BY_ID = "SYSTEM",
                    TEAM_ID = "DEFAULT_TEAM",
                };

                // 2. 创建测试SERVER_EVENT - AddAfter事件
                var addEvent = new SERVER_EVENT
                {
                    ID = Guid.NewGuid().ToString("N"),
                    SOURCE_ID = "6F83A1B4C5D6E7F8A9B0C1D2E3F4A5BA", // 假设这是DOCUMENT的ITEMTYPE ID
                    RELATED_ID = testMethod.ID,
                    EVENT_TYPE = "AddAfter",
                    EVENT_VERSION = "version_1",
                    CREATED_BY_ID = "SYSTEM",
                    CREATED_ON = DateTime.Now,
                    CONFIG_ID = "DEFAULT_CONFIG",
                    PERMISSION_ID = "DEFAULT_PERMISSION",
                    OWNED_BY_ID = "SYSTEM",
                    TEAM_ID = "DEFAULT_TEAM",
                };

                // 3. 创建测试SERVER_EVENT - UpdateAfter事件
                var updateEvent = new SERVER_EVENT
                {
                    ID = Guid.NewGuid().ToString("N"),
                    SOURCE_ID = "DOCUMENT_ITEMTYPE",
                    RELATED_ID = testMethod.ID,
                    EVENT_TYPE = "UpdateAfter",
                    EVENT_VERSION = "version_1",
                    CREATED_BY_ID = "SYSTEM",
                    CREATED_ON = DateTime.Now,
                    CONFIG_ID = "DEFAULT_CONFIG",
                    PERMISSION_ID = "DEFAULT_PERMISSION",
                    OWNED_BY_ID = "SYSTEM",
                    TEAM_ID = "DEFAULT_TEAM",
                };

                // 保存到数据库
                await _methodService.CreateAsync(testMethod);
                await _serverEventService.CreateAsync(addEvent);
                await _serverEventService.CreateAsync(updateEvent);

                return ApiResponse<string>.Ok(
                    $"Test data created successfully. Method ID: {testMethod.ID}"
                );
            }
            catch (Exception ex)
            {
                return ApiResponse<string>.Exception(
                    $"Failed to create test data: {ex.Message}",
                    ex.ToString()
                );
            }
        }

        /// <summary>
        /// 测试创建事件
        /// </summary>
        [HttpPost("test-create-event")]
        public async Task<ApiResponse<DOCUMENT>> TestCreateEvent()
        {
            try
            {
                var testDocument = new DOCUMENT
                {
                    ID = Guid.NewGuid().ToString("N"),
                    KEYED_NAME = "Test Document",
                    NAME = "Test Document",
                    DESCRIPTION = "Original description",
                    CREATED_BY_ID = "SYSTEM",
                    CREATED_ON = DateTime.Now,
                    CONFIG_ID = "DEFAULT_CONFIG",
                    PERMISSION_ID = "DEFAULT_PERMISSION",
                    OWNED_BY_ID = "SYSTEM",
                    TEAM_ID = "DEFAULT_TEAM",
                    STATE = "Active",
                    IS_CURRENT = true,
                };

                var result = await _documentService.CreateAsync(testDocument);

                return ApiResponse<DOCUMENT>.Ok(result);
            }
            catch (Exception ex)
            {
                return ApiResponse<DOCUMENT>.Exception(
                    $"Failed to test create event: {ex.Message}",
                    ex.ToString()
                );
            }
        }

        /// <summary>
        /// 测试更新事件
        /// </summary>
        [HttpPut("test-update-event/{id}")]
        public async Task<ApiResponse<DOCUMENT>> TestUpdateEvent(string id)
        {
            try
            {
                var document = await _documentService.GetByIdAsync(id);
                if (document == null)
                {
                    return ApiResponse<DOCUMENT>.Fail("Document not found");
                }

                document.DESCRIPTION = "Updated description - " + DateTime.Now.ToString();
                document.MODIFIED_BY_ID = "SYSTEM";
                document.MODIFIED_ON = DateTime.Now;

                var result = await _documentService.UpdateAsync(document);

                return ApiResponse<DOCUMENT>.Ok(result);
            }
            catch (Exception ex)
            {
                return ApiResponse<DOCUMENT>.Exception(
                    $"Failed to test update event: {ex.Message}",
                    ex.ToString()
                );
            }
        }

        /// <summary>
        /// 测试删除事件
        /// </summary>
        [HttpDelete("test-delete-event/{id}")]
        public async Task<ApiResponse<bool>> TestDeleteEvent(string id)
        {
            try
            {
                var result = await _documentService.DeleteAsync(id);
                return ApiResponse<bool>.Ok(result);
            }
            catch (Exception ex)
            {
                return ApiResponse<bool>.Exception(
                    $"Failed to test delete event: {ex.Message}",
                    ex.ToString()
                );
            }
        }

        /// <summary>
        /// 完整的事件测试流程
        /// </summary>
        [HttpPost("test-full-event-flow")]
        public async Task<ApiResponse<EventTestResult>> TestFullEventFlow()
        {
            var result = new EventTestResult();

            try
            {
                // 步骤1: 创建测试数据
                var setupResult = await SetupTestData();
                if (!setupResult.Success)
                {
                    result.Success = false;
                    result.Message = "Failed to setup test data";
                    result.Error = setupResult.Error;
                    return ApiResponse<EventTestResult>.Ok(result);
                }
                result.TestDataCreated = true;

                // 步骤2: 测试创建事件
                var createResult = await TestCreateEvent();
                result.CreatedDocument = createResult.Data;
                result.CreateEventTriggered =
                    createResult.Data?.KEYED_NAME?.Contains("_Processed_") ?? false;

                // 步骤3: 测试更新事件
                if (createResult.Data != null)
                {
                    var updateResult = await TestUpdateEvent(createResult.Data.ID);
                    result.UpdatedDocument = updateResult.Data;
                    result.UpdateEventTriggered =
                        updateResult.Data?.DESCRIPTION?.Contains("Processed by event handler")
                        ?? false;
                }

                // 步骤4: 测试删除事件
                if (createResult.Data != null)
                {
                    var deleteResult = await TestDeleteEvent(createResult.Data.ID);
                    result.DeleteEventTriggered = deleteResult.Data;
                }

                result.Success = true;
                result.Message = "Full event flow test completed successfully";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Message = $"Test failed: {ex.Message}";
                result.Error = ex.ToString();
            }

            return ApiResponse<EventTestResult>.Ok(result);
        }

        /// <summary>
        /// 验证事件触发状态
        /// </summary>
        [HttpGet("verify-event-trigger/{documentId}")]
        public async Task<ApiResponse<EventVerificationResult>> VerifyEventTrigger(
            string documentId
        )
        {
            try
            {
                var document = await _documentService.GetByIdAsync(documentId);
                if (document == null)
                {
                    return ApiResponse<EventVerificationResult>.Fail("Document not found");
                }

                var verification = new EventVerificationResult
                {
                    DocumentId = documentId,
                    KeyedName = document.KEYED_NAME,
                    Description = document.DESCRIPTION,
                    CreateEventTriggered = document.KEYED_NAME?.Contains("_Processed_") ?? false,
                    UpdateEventTriggered =
                        document.DESCRIPTION?.Contains("Processed by event handler") ?? false,
                    LastModified = document.MODIFIED_ON,
                };

                return ApiResponse<EventVerificationResult>.Ok(verification);
            }
            catch (Exception ex)
            {
                return ApiResponse<EventVerificationResult>.Exception(
                    $"Failed to verify event trigger: {ex.Message}",
                    ex.ToString()
                );
            }
        }

        /// <summary>
        /// 清理测试数据
        /// </summary>
        [HttpDelete("cleanup-test-data")]
        public async Task<ApiResponse<string>> CleanupTestData()
        {
            try
            {
                // 删除测试用的SERVER_EVENT记录
                var testEvents = await _freeSql
                    .Select<SERVER_EVENT>()
                    .Where(se => se.CREATED_BY_ID == "SYSTEM")
                    .ToListAsync();

                foreach (var testEvent in testEvents)
                {
                    await _serverEventService.DeleteAsync(testEvent.ID);
                }

                // 删除测试用的METHOD记录
                var testMethods = await _freeSql
                    .Select<METHOD>()
                    .Where(m => m.CREATED_BY_ID == "SYSTEM")
                    .ToListAsync();

                foreach (var testMethod in testMethods)
                {
                    await _methodService.DeleteAsync(testMethod.ID);
                }

                // 删除测试用的DOCUMENT记录
                var testDocuments = await _freeSql
                    .Select<DOCUMENT>()
                    .Where(d => d.CREATED_BY_ID == "SYSTEM")
                    .ToListAsync();

                foreach (var testDocument in testDocuments)
                {
                    await _documentService.DeleteAsync(testDocument.ID);
                }

                return ApiResponse<string>.Ok(
                    $"Test data cleaned up successfully. Removed {testEvents.Count} events, {testMethods.Count} methods, {testDocuments.Count} documents."
                );
            }
            catch (Exception ex)
            {
                return ApiResponse<string>.Exception(
                    $"Failed to cleanup test data: {ex.Message}",
                    ex.ToString()
                );
            }
        }

        /// <summary>
        /// 获取测试状态
        /// </summary>
        [HttpGet("test-status")]
        public async Task<ApiResponse<object>> GetTestStatus()
        {
            try
            {
                var eventCount = await _freeSql
                    .Select<SERVER_EVENT>()
                    .Where(se => se.CREATED_BY_ID == "SYSTEM")
                    .CountAsync();

                var methodCount = await _freeSql
                    .Select<METHOD>()
                    .Where(m => m.CREATED_BY_ID == "SYSTEM")
                    .CountAsync();

                var documentCount = await _freeSql
                    .Select<DOCUMENT>()
                    .Where(d => d.CREATED_BY_ID == "SYSTEM")
                    .CountAsync();

                var status = new
                {
                    TestEventsCount = eventCount,
                    TestMethodsCount = methodCount,
                    TestDocumentsCount = documentCount,
                    HasTestData = eventCount > 0 || methodCount > 0 || documentCount > 0,
                    Message = eventCount > 0
                        ? "Test data is ready for testing"
                        : "No test data found. Please setup test data first.",
                };

                return ApiResponse<object>.Ok(status);
            }
            catch (Exception ex)
            {
                return ApiResponse<object>.Exception(
                    $"Failed to get test status: {ex.Message}",
                    ex.ToString()
                );
            }
        }
    }
}
